<?php
/**
 * Created by PhpStorm.
 * User: xiongweixing
 * Date: 2017/12/7
 * Time: 15:46
 */

namespace Service;

use Illuminate\Support\Facades\Redis;
use Wxxiong6\WxxLogger\WxxLogger as Logger;

class TokenService extends BaseService
{
    /**
     * @var int 有效期
     */
    private $expire;

    /**
     * @var string
     */
    private $tokeListName = 'tokenList';

    /**
     * 创建Token
     * @param $uid
     * @return mixed
     */
    public function createToken($uid)
    {
        if ($uid < 1) {
            return false;
        }
        $tokenListName = $this->tokeListName;
        $tokenInfo['uid']          = $uid;
        $tokenInfo['created_at']   = time();
        $tokenInfo['expire']       = $tokenInfo['created_at'] + $this->getExpire(); //15天
        $tokenInfo['updated_at']   = $tokenInfo['created_at'];
        $token     = md5($uid . '*' . $tokenInfo['expire']);
        $tokenName = $this->getTokenName($token);
        $expire    = $this->getExpire();
        //检查根据TokenList是否存在
        $isExists = Redis::hexists($tokenListName, $uid);
        if ($isExists) {
            $oldToken = Redis::hget($tokenListName, $uid);
            if ($oldToken != $token) {
                //更新token
                Redis::hset($tokenListName, $uid, $token);
                Logger::info("用户uid:'{$uid}',oldToken：'{$oldToken}',变更为newToken:'{$token}'");
                //查询token表是否存在
                if (Redis::hexists($this->getTokenName($oldToken), 'uid')) {
                    Redis::del($this->getTokenName($oldToken));
                    Logger::debug("删除原Token：'{$this->getTokenName($oldToken)}'");
                }
            }

        } else {
            Redis::hmset($tokenListName, [ $uid => $token]);
            Logger::debug("更新原Token：'{$tokenListName}'， uid:'{$uid}',token:'{$token}'");
        }
        Redis::hmset($tokenName, $tokenInfo);
        Redis::expire($tokenName, $expire);
        Logger::info("设置新Token：'{$tokenName}'， expire:'{$expire}'");
        $tokenInfo['token'] = $token;
        return $tokenInfo;
    }

    /**
     * 获取Redis TokenName
     * @param $token
     * @return string
     */
    public function getTokenName($token)
    {
        return 'token:' . $token;
    }


    /**
     * 检查Token，验证通过更新有效期,更新更新时间
     * @param $token
     * @return bool|int
     */
    public function checkToken($token)
    {
        $tokenName = $this->getTokenName($token);
        $uid = Redis::hget($tokenName, 'uid');
        if (empty($uid)) {
            logger::info("token较验失败'{$uid}'为空,token:{$tokenName}不存在");
            return false;
        }
        Redis::hmset($tokenName, ['updated_at' => time()]);
        Redis::expire($tokenName, $this->getExpire());
        logger::info("更新：token:'{$tokenName}'，有效期{$this->getExpire()},uid：'{$uid}'");
        return (int) $uid;
    }

    /**
     * 删除token
     * @param $token
     * @return bool
     */
    public function deleteToken($token)
    {
        $tokenName = $this->getTokenName($token);
        $uid = Redis::hget($tokenName, 'uid');
        if (empty($uid)) {
            logger::info("'{$uid}'为空,token'{$tokenName}'不存在");
            return true;
        }

        if (Redis::hdel($this->tokeListName, $uid)) {
            logger::debug("删除'{$this->tokeListName}':'{$uid}'成功");
        } else {
            logger::debug("删除'{$this->tokeListName}':'{$uid}'失败");
        }

        if (Redis::del($tokenName)) {
            logger::debug("删除'{$tokenName}'成功");
        } else {
            logger::debug("删除'{$tokenName}'失败");
        }
        return true;
    }

    /**
     * @return mixed
     */
    public function getExpire()
    {
        if (empty($this->expire)) {
            $this->setExpire();
        }
        return $this->expire;
    }

    /**
     * 将签名过期时间指定为自 Epoch (1970 年 1 月 1 日 00:00:00 UTC) 以来的秒数。
     * @param int $expire 有效期
     */
    public function setExpire($expire = 0)
    {
        if ($expire === 0) {
            $expire = 15 * 24 * 3600;
        }
        $this->expire = $expire;
    }

}
